# Top-level Makefile for Compiler Project
# Calls subdirectory Makefiles and unifies library output location

# Define subdirectories and build order
SUBDIRS = core vm lexer parser code_eval

# Library directory
LIB_DIR = lib

# Define platform-specific suffixes
ifeq ($(OS),Windows_NT)
    LIB_SUFFIX = .dll
else
    UNAME_S := $(shell uname -s)
    ifeq ($(UNAME_S),Darwin)
        LIB_SUFFIX = .dylib
    else
        LIB_SUFFIX = .so
    endif
endif

# Library files
CORE_LIB = $(LIB_DIR)/core2$(LIB_SUFFIX)
VM_LIB = $(LIB_DIR)/cvm2$(LIB_SUFFIX)
LEXER_LIB = $(LIB_DIR)/clexer2$(LIB_SUFFIX)
PARSER_LIB = $(LIB_DIR)/cparser2$(LIB_SUFFIX)
CODE_EVAL_LIB = $(LIB_DIR)/eval_excute2$(LIB_SUFFIX)

# Default target - Build all modules in sequence
all: create_lib_dir core vm lexer parser code_eval test-instruction test-print-symbol

# Create library directory
.PHONY: create_lib_dir
create_lib_dir:
	@mkdir -p $(LIB_DIR)
	@echo "Created library directory: $(LIB_DIR)"

# Build core module
.PHONY: core
core: create_lib_dir
	@echo "Building core module..."
	@cd core && $(MAKE) LIB_DIR=../$(LIB_DIR)

# Build vm module, depends on core
.PHONY: vm
vm: core
	@echo "Building vm module..."
	@cd vm && $(MAKE) LIB_DIR=../$(LIB_DIR)

# Build lexer module, depends on core and vm
.PHONY: lexer
lexer: vm
	@echo "Building lexer module..."
	@cd lexer && $(MAKE) LIB_DIR=../$(LIB_DIR)

# Build parser module, depends on lexer
.PHONY: parser
parser: lexer
	@echo "Building parser module..."
	@cd parser && $(MAKE) LIB_DIR=../$(LIB_DIR)

# Build code_eval module, depends on parser
.PHONY: code_eval
code_eval: parser
	@echo "Building code_eval module..."
	@cd code_eval && $(MAKE) LIB_DIR=../$(LIB_DIR)

# Build standalone parser test program
.PHONY: test-parser
test-parser: all
	@echo "Building parser test program..."
	@cd parser && $(MAKE) parser_test.exe LIB_DIR=../$(LIB_DIR)

# Build standalone lexer test program
.PHONY: test-lexer
test-lexer: all
	@echo "Building lexer test program..."
	@cd lexer && $(MAKE) c_lexer.exe LIB_DIR=../$(LIB_DIR)

.PHONY: test-instruction
test-instruction: all
	@echo "Building instruction test program..."
	@cd parser && $(MAKE) print_instruction_test LIB_DIR=../$(LIB_DIR)

.PHONY: test-print-symbol
test-print-symbol: all
	@echo "Building print_symbol test program..."
	@cd parser && $(MAKE) print_symbol_test LIB_DIR=../$(LIB_DIR)


# Python UI
.PHONY: python_ui
python_ui:
	@echo "使用Python界面"
	@echo "运行: python main.py"


# Clean all generated files
.PHONY: clean
clean:
	@echo "Cleaning core module..."
	@$(MAKE) -C core clean LIB_DIR=../$(LIB_DIR)
	@echo "Cleaning vm module..."
	@$(MAKE) -C vm clean LIB_DIR=../$(LIB_DIR)
	@echo "Cleaning lexer module..."
	@$(MAKE) -C lexer clean LIB_DIR=../$(LIB_DIR)
	@echo "Cleaning parser module..."
	@$(MAKE) -C parser clean LIB_DIR=../$(LIB_DIR)
	@echo "Cleaning code_eval module..."
	@$(MAKE) -C code_eval clean LIB_DIR=../$(LIB_DIR)
	@echo "Cleaning $(LIB_DIR) contents..."
	@rm -f $(LIB_DIR)/*$(LIB_SUFFIX)
	@rm -f temp_code_*.c
	@echo "Clean completed"
	

# Run tests
.PHONY: test
test: all
	@echo "Running tests..."
	@if [ -f "$(LEXER_LIB)" ] && [ -f "$(VM_LIB)" ] && [ -f "$(CORE_LIB)" ] && [ -f "$(PARSER_LIB)" ] && [ -f "$(CODE_EVAL_LIB)" ]; then \
		echo "All library files built successfully"; \
	else \
		echo "Build failed, missing library files"; \
		exit 1; \
	fi

# Help information
.PHONY: help
help:
	@echo "Available targets:"
	@echo "  all         - Build all modules"
	@echo "  clean       - Clean all generated files"
	@echo "  test        - Run tests"
	@echo "  test-lexer  - Build lexer test program"
	@echo "  test-parser - Build parser test program"
	@echo "	 test-instruction - Build instruction_print program"
	@echo "  core        - Build core module only"
	@echo "  vm          - Build core and vm modules"
	@echo "  lexer       - Build core, vm, and lexer modules"
	@echo "  parser      - Build core, vm, lexer, and parser modules"
	@echo "  code_eval   - Build all modules including code_eval"
	@echo "  python_ui   - Build Python UI"
	@echo "  help        - Display this help information"
	@echo ""
	@echo "Current settings:"
	@echo "  Library directory: $(LIB_DIR)"
	@echo "  Library suffix: $(LIB_SUFFIX)"

